﻿using Abp.Application.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Json;
using Abp.Web.Models;
using KelonProud.Extensions;
using KelonProud.Mvc;
using KelonProud.TableManagement.Domain;
using KelonProud.TableManagement.Dtos.DataBase;
using KelonProud.TableManagement.Managers;

namespace KelonProud.TableManagement.Services
{
    public interface IKelonDataBaseAppService : IAsyncCrudAppService<DataBaseOutput, int, PagedResultRequestDto, DataBaseInput, DataBaseOutput>
    {
        List<object> GetDataBaseTypeJson();

        Task<DataBaseSearchOutput> GetDataBases(DataBaseSearchInput searchInput);
    }

    public class KelonDataBaseAppService : KelonProudAsyncCrudAppService<KelonDataBase, DataBaseOutput, int, PagedResultRequestDto, DataBaseInput, DataBaseOutput>, IKelonDataBaseAppService
    {
        private readonly KelonDataBaseManager _dataBaseManager;

        public KelonDataBaseAppService(IRepository<KelonDataBase, int> repository, KelonDataBaseManager dataBaseManager) : base(repository)
        {
            _dataBaseManager = dataBaseManager;
        }

        public override async Task<DataBaseOutput> Save(DataBaseInput input)
        {
            var database = await _dataBaseManager.GetByIdtAsync(input.Id) ?? new KelonDataBase();
            database.Name = input.Name;
            database.Type = input.Type;
            database.ConfigJson = new DataBaseConfigModel()
            {
                User = input.ConfigUser,
                Name = input.ConfigName,
                PassWord = input.ConfigPassWord,
                Ip = input.ConfigIp,
                Port = input.ConfigPort
            }.ToJsonString();

            database.Id =   _dataBaseManager.SaveDataBase(database);

            return database.MapTo<DataBaseOutput>();
        }

        public List<object> GetDataBaseTypeJson()
        {
            var result = new List<object>();

            var types = typeof(DataBaseType).GetEmunDictionary();

            types.Each(e =>
            {
                result.Add(new { id = e.Value,name=e.Key });
            });

            return result;
        }

        public override Task Delete(EntityDto<int> input)
        {
            return base.Delete(input);
        }

        [WrapResult(WrapOnSuccess = false)]
        public Task<DataBaseSearchOutput> GetDataBases(DataBaseSearchInput searchInput)
        {
            var result = new DataBaseSearchOutput();{ };
            var query = _dataBaseManager.Query;

            if (searchInput.Name.HasValue())
            {
                query = query.Where(w => w.Name.Contains(searchInput.Name));
            }

            if (searchInput.Type.HasValue() && searchInput.Type != "-1")
            {
                query = query.Where(w => w.Type.ToString() == searchInput.Type);
            }

            result.Total = query.Count();
            result.Rows = query.Skip(searchInput.SkipCount).Take(searchInput.SearchCount).ToList()
                .Select(s => s.MapTo<DataBaseOutput>()).ToList();

            return Task.FromResult(result);
        }
    }
}
